// HookDll.cpp : Defines the entry point for the DLL application.
//

#include "stdafx.h"
#include "HookDll.h"
#include "detours.h"
#include "winsock2.h"
#include "stdio.h"


#ifdef _MANAGED
#pragma managed(push, off)
#endif

#pragma comment(lib,"ws2_32.lib")
#pragma comment(lib,"detours.lib")
#pragma comment(lib,"detoured.lib")

static int   (WINAPI * TrueConnect)(SOCKET s, const struct sockaddr FAR *name, int namelen) = connect;

static int   (WINAPI * TrueWSARecv)(SOCKET s,LPWSABUF lpBuffers,DWORD dwBufferCount,LPDWORD lpNumberOfBytesRecvd,LPDWORD lpFlags,LPWSAOVERLAPPED lpOverlapped,LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine) = WSARecv;

static int   (WINAPI * TrueWSASend)(SOCKET s,LPWSABUF lpBuffers,DWORD dwBufferCount,LPDWORD lpNumberOfBytesSent,DWORD dwFlags,LPWSAOVERLAPPED lpOverlapped,LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine)=WSASend;


__declspec(dllexport) void WINAPI NewConnect(SOCKET s, const struct sockaddr FAR *name, int namelen)
{
	char     buf[128]={0};    
	SOCKADDR_IN * saServer = (struct sockaddr_in *)name;    
	sprintf(buf, "IP=%s Port=%d",::inet_ntoa(saServer->sin_addr),::ntohs(saServer->sin_port));
	TrueConnect(s, name, namelen);
}

int WINAPI NewWSARecv(SOCKET s,LPWSABUF lpBuffers,DWORD dwBufferCount,LPDWORD lpNumberOfBytesRecvd,LPDWORD lpFlags,LPWSAOVERLAPPED lpOverlapped,LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine)
{
	int ret;
	ret = TrueWSARecv(s,lpBuffers,dwBufferCount,lpNumberOfBytesRecvd,lpFlags,lpOverlapped,lpCompletionRoutine);
	//MessageBox(NULL,"lpBuffers->buf","wsarecv hooked",NULL);    
	return ret;

}

int WINAPI NewWSASend(SOCKET s,LPWSABUF lpBuffers,DWORD dwBufferCount,LPDWORD lpNumberOfBytesSent,DWORD dwFlags,LPWSAOVERLAPPED lpOverlapped,LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine)
{ 
	int ret=TrueWSASend(s,lpBuffers,dwBufferCount,lpNumberOfBytesSent,dwFlags,lpOverlapped,lpCompletionRoutine);
	return ret;
}

BOOL APIENTRY DllMain( HMODULE hModule,
					  DWORD  ul_reason_for_call,
					  LPVOID lpReserved
					  )
{
	switch (ul_reason_for_call)
	{
	case DLL_PROCESS_ATTACH:
	case DLL_THREAD_ATTACH:
		TCHAR lib_name[MAX_PATH]; 
        ::GetModuleFileName( hModule, lib_name, MAX_PATH );
        ::LoadLibrary( lib_name );
		DetourTransactionBegin();
		DetourUpdateThread(GetCurrentThread());   
		DetourAttach(&(PVOID&)TrueConnect, NewConnect);
		DetourAttach(&(PVOID&)TrueWSARecv, NewWSARecv);    
		DetourAttach(&(PVOID&)TrueWSASend, NewWSASend);
		DetourTransactionCommit();
		DetourRestoreAfterWith();    
		break;
	case DLL_THREAD_DETACH:;
	case DLL_PROCESS_DETACH:
		DetourTransactionBegin();
		DetourUpdateThread(GetCurrentThread());
		DetourDetach(&(PVOID&)TrueConnect, NewConnect);
		DetourDetach(&(PVOID&)TrueWSARecv, NewWSARecv);
		DetourDetach(&(PVOID&)TrueWSASend, TrueWSASend);
		DetourTransactionCommit();
		break;
	}
	return TRUE;
}

#ifdef _MANAGED
#pragma managed(pop)
#endif

// This is an example of an exported variable
HOOKDLL_API int nHookDll=0;
HOOKDLL_API HINSTANCE hinstDLL; 
HOOKDLL_API HHOOK hhookSysMsg;

// This is an example of an exported function.
HOOKDLL_API int fnHookDll(void)
{
	return 42;
}

// This is the constructor of a class that has been exported.
// see HookDll.h for the class definition
CHookDll::CHookDll()
{
	return;
}


LRESULT CALLBACK KeyboardProc(int nCode,WPARAM wParam,LPARAM lParam)
{
	return CallNextHookEx(hhookSysMsg,nCode,wParam,lParam);
}

HOOKDLL_API int InstallHook(void){
	hinstDLL = GetModuleHandle(L"HookDll"); 
	hhookSysMsg = SetWindowsHookEx(WH_KEYBOARD,KeyboardProc,hinstDLL,0);
	return true;
}

HOOKDLL_API int UnLoadHook(void){
	BOOL result=::UnhookWindowsHook(WH_KEYBOARD,KeyboardProc);
	return true;
}